package com.xzy.sms.web.domain.service;

import java.util.Date;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.xzy.sms.web.domain.dao.UserDao;
import com.xzy.sms.web.domain.entity.User;
import com.xzy.sms.web.system.utils.UserUtils;

/**
 * @desc 
 * @author wjw
 * @time 2017年11月16日下午3:34:16
 */
@Service
@Transactional
public class UserService {
    
    protected Logger logger = LoggerFactory.getLogger(getClass());
    
    /** 用户 */
    @Autowired
    private UserDao userDao;
    
    /**
     * 根据id查找用户
     * @param id xx
     * @return xx
     */
    @Transactional(readOnly = true)
    public User findUser(String id) {
        return userDao.getOne(id);
    }
    
    /**
     * 查找当前用户
     * @return 当前用户
     */
    @Transactional(readOnly = true)
    public User findCurrentUser() {
        String id = UserUtils.getUserId();
        return userDao.getOne(id);
    }
    
    /**
     * 保存用户
     * @param entity xx
     * @return xx
     */
    public User saveUser(User entity) {
        return userDao.save(entity);
    }
    
    /**
     * 逻辑删除用户
     * @param id xx
     */
    public void deleteUser(String id) {
        userDao.setDelFlag(id);
    }
    
    /**
     * 查询用户
     * @param serchkey 查询条件
     * @param pageNumber xx
     * @param pageSize xx
     * @return xx
     */
    @Transactional(readOnly = true)
    public Page<User> findByKeyword(String serchkey, int pageNumber, int pageSize) {
        return this.findByKeyword(serchkey, pageNumber, pageSize, new Sort(Direction.DESC, "userId"));
    }
    
    /**
     * 查询用户
     * @param serchkey 查询条件
     * @param pageNumber xx
     * @param pageSize xx
     * @param sort 自定义排序
     * @return xx
     */
    @Transactional(readOnly = true)
    public Page<User> findByKeyword(String serchkey, int pageNumber, int pageSize, Sort sort) {
        // pageNumber要从0开始，所以需要减一
        PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize, sort);
        Specification<User> spec = buildSpecification(serchkey);
        return userDao.findAll(spec, pageRequest);
    }
    
    /**
     * 构建查询条件
     * @param keyword keyword
     * @param orgId 只查找该根节点下面数据
     * @param type type
     * @return spec
     */
    private Specification<User> buildSpecification(final String keyword) {
        Specification<User> spec = new Specification<User>() {
            
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                List<Predicate> predicates = Lists.newArrayList();
                if (StringUtils.isNotEmpty(keyword)) {// 根据name like
                    String queryKey = convertMySqlString(keyword);
                    Path<String> expression = root.get("account");
                    Predicate predicateName = builder.like(expression, "%" + queryKey + "%", '/');
                    predicates.add(builder.or(predicateName));
                }
                //不查询超级管理员账户admin或superadmin
                predicates.add(builder.notEqual(root.get("account"), "admin"));
                predicates.add(builder.notEqual(root.get("account"), "superadmin"));
                predicates.add(builder.equal(root.get("delFlag"), User.DEL_FLAG_NORMAL));
                // 将所有条件用 and 联合起来
                if (predicates.size() > 0) {
                    return builder.and(predicates.toArray(new Predicate[predicates.size()]));
                }
                
                return builder.conjunction();
            }
        };
        return spec;
    }
    
    /**
     * mysql模糊查询时，如果查询关键字本身包含_和%，需要转义
     * @param queryKey 查询关键字
     * @return 转义字符
     */
    private String convertMySqlString(String queryKey) {
        String[] encodeArr = { "_", "%" };
        String rst = queryKey;
        for (String encode : encodeArr) {
            rst = StringUtils.replace(rst, encode, "/" + encode);
        }
        return rst;
    }
    
    /**
     * 根据用户名 查找用户
     * @param account 帐号
     * @return user
     */
    @Transactional(readOnly = true)
    public User findByAccount(String account) {
        return userDao.findByAccount(account);
    }
    
    /**
     * 修改密码
     * @param password password
     * @param userId userId
     */
    public void updatePasswordById(String password, String userId) {
        userDao.updatePasswordById(password, new Date(), userId);
    }
}
